<!--
 * @Description: 新建隧道
 * @Author: 0001100986/LiuShuai
 * @Date: 2021-07-17 09:04:06
 * @LastEditTime: 2021-11-11 16:17:59
 * @LastEditors: 0001100986/LiuShuai
-->
<template>
  <div class="tunnel-content">
    <div class="info">
      <h1 class="title">新建隧道</h1>
      <el-alert
        title="友情提示：隧道两端如果都是INTERNET链路，且都是私网地址，是无法成功建链的！建议隧道两端WAN口选择的时候，尽量使用相同运营商，获得更好的客户体验！"
        type="warning"
        show-icon
      ></el-alert>
      <el-form :model="form" class="form" :rules="rules" ref="tunnelForm" label-width="80px">
        <!-- 名称 -->
        <el-form-item label="名称" prop="userlabel" key="userlabel">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-input v-model="form.userlabel" maxlength="200" />
          </el-col>
        </el-form-item>
        <!-- 类型 -->
        <el-form-item label="类型" prop="tunnelType" key="tunnelType">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-select v-model="form.tunnelType" style="width: 100%;">
              <el-option value="IPSEC" label="IPSEC"></el-option>
              <el-option value="L2TP" label="L2TP"></el-option>
            </el-select>
          </el-col>
        </el-form-item>
        <!-- IP类型 -->
        <el-form-item label="IP类型" prop="ipVersion" key="ipVersion">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-select v-model="form.ipVersion" style="width: 100%;">
              <el-option value="V4" label="IPv4"></el-option>
              <el-option value="V6" label="IPv6"></el-option>
            </el-select>
          </el-col>
        </el-form-item>
        <!-- 优先级 -->
        <el-form-item label="优先级" prop="priority" key="priority">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-select v-model="form.priority" style="width: 100%;">
              <el-option value="HIGH" label="高"></el-option>
              <el-option value="LOW" label="低"></el-option>
            </el-select>
          </el-col>
        </el-form-item>
        <!-- 源端 -->
        <el-form-item label="源" prop="start" key="start">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-cascader
              v-model="form.start"
              :props="startOptions"
              style="width: 100%;"
              @change="handleChange"
              clearable
            ></el-cascader>
          </el-col>
        </el-form-item>
        <template v-if="form.start.length === 4">
          <!-- 开启VPN -->
          <el-form-item label="开启VPN" prop="enableVpn" key="enableVpn">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-switch v-model="form.enableVpn"></el-switch>
            </el-col>
          </el-form-item>
          <!-- VPN -->
          <el-form-item
            label="VPN"
            prop="vpnId"
            key="vpnId"
            v-if="form.enableVpn"
            :rules="{
              required: true,
              message: '请选择VPN',
              trigger: 'change'
            }"
          >
            <el-col :xs="24" :sm="12" :lg="6">
              <el-select v-model="form.vpnId" style="width: 100%;">
                <el-option
                  v-for="item in vpnls"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-col>
          </el-form-item>
          <!-- 源端接口地址 -->
          <el-form-item label="接口地址" class="ip-mask">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model="form.startNeIpsecIp" placeholder="IP地址" />
              <label>/</label>
              <el-input v-model.number="form.startMask" placeholder="掩码" />
            </el-col>
          </el-form-item>
          <!-- 目的端 -->
          <el-form-item label="目的" prop="end" key="end">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-cascader v-model="form.end" :props="endOptions" style="width: 100%;" clearable></el-cascader>
            </el-col>
          </el-form-item>
          <!-- 目的端接口地址 -->
          <el-form-item v-if="form.end.length === 4" label="接口地址" class="ip-mask">
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model="form.endNeIpsecIp" placeholder="IP地址" />
              <label>/</label>
              <el-input v-model.number="form.endMask" placeholder="掩码" />
            </el-col>
          </el-form-item>
        </template>
        <!-- 监控 -->
        <el-form-item label="监控" prop="enableSqa" key="enableSqa">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-switch v-model="form.enableSqa"></el-switch>
          </el-col>
        </el-form-item>
        <!-- 限速 -->
        <el-form-item label="限速" prop="speed" key="speed">
          <el-col :xs="24" :sm="12" :lg="6">
            <el-switch v-model="form.speed"></el-switch>
          </el-col>
        </el-form-item>
        <template v-if="form.speed">
          <!-- 带宽 -->
          <el-form-item
            label="带宽"
            prop="rateLimit"
            key="rateLimit"
            :rules="[
              { required: true, message: '不能为空', trigger: 'blur'},
              { type: 'number', message: '范围：1-100', min: 1, max: 100, trigger: 'blur'}
            ]"
          >
            <el-col :xs="24" :sm="12" :lg="6">
              <el-input v-model.number="form.rateLimit">
                <template slot="append">Mbps</template>
              </el-input>
            </el-col>
          </el-form-item>
        </template>
        <el-form-item>
          <el-button style="width: 90px" @click="cancel">返回</el-button>
          <el-button type="primary" style="width: 90px" @click="submitForm('tunnelForm')">创建</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
export default {
  props: ['tenants'],
  created () {
    let tenants = this.tenants;
    this.startOptions = {
      lazy: true,
      lazyLoad: (node, resolve) => {
        const { level } = node;
        // 初始一级参数
        if (level === 0) {
          let nodes = tenants.map(item => {
            return {
              value: item.value,
              label: item.label,
              leaf: level >= 3
            };
          });
          resolve(nodes);
        }
        // 二级
        if (level === 1) {
          this.$http.get({
            url: '/api/sdwan/site/getSiteListByDgId/' + node.data.value
          }).then(res => {
            let { status, resultBody } = res;
            if (status === '0') {
              let sites = [];
              resultBody.map(item => {
                if (item.siteType === 'CPE') {
                  sites.push({
                    value: item.id,
                    label: item.sitename,
                    info: item,
                    leaf: level >= 3
                  });
                }
              });
              resolve(sites);
            }
          });
        }
        // 三级
        if (level === 2) {
          this.site = node.data.info;
          let neArry = node.data.info.nes;
          // 判断是否存在网元
          if (neArry.length === 0) {
            let nes = [];
            resolve(nes);
          } else {
            let nes = neArry.map((item) => {
              return {
                value: item.ne.id,
                label: item.ne.userlabel,
                info: item,
                wans: node.data.info.wans,
                leaf: level >= 3
              };
            });
            resolve(nes);
          }
        }
        // 四级
        if (level === 3) {
          let wans = node.data.wans;
          let info = node.data.info;
          let arry = [];
          this.site.lans.map(item => {
            arry.push({
              value: item.vpnId,
              label: item.vpnUserLabel
            });
          });
          this.vpnls = this.uniqueArr(arry, 'value');
          let wan = [];
          wans.map(it => {
            if (it.standByRelation === info.standByRelation) {
              wan.push({
                value: it.name,
                label: it.alias,
                wan: it,
                leaf: level >= 3
              });
            }
          });
          resolve(wan);
        }
      }
    };
    this.endOptions = {
      lazy: true,
      lazyLoad: (node, resolve) => {
        const { level } = node;
        // 初始一级参数
        if (level === 0) {
          if (this.form.start.length === 4) {
            let nodes = [{
              value: 100000,
              label: 'Default'
            }];
            tenants.map(item => {
              if (item.value === this.form.start[0]) {
                nodes.push({
                  value: item.value,
                  label: item.label,
                  leaf: level >= 3
                });
              }
            });
            resolve(nodes);
          }
        }
        // 二级
        if (level === 1) {
          this.$http.get({
            url: '/api/sdwan/site/getSiteListByDgId/' + node.data.value
          }).then(res => {
            let { status, resultBody } = res;
            if (status === '0') {
              let sites = [];
              resultBody.map(item => {
                if (item.id !== this.form.start[1]) {
                  sites.push({
                    value: item.id,
                    label: item.sitename,
                    info: item,
                    leaf: level >= 3
                  });
                }
              });
              resolve(sites);
            }
          });
        }
        // 三级
        if (level === 2) {
          let neArry = node.data.info.nes;
          // 判断是否存在网元
          if (neArry.length === 0) {
            let nes = [];
            resolve(nes);
          } else {
            let nes = neArry.map((item) => {
              return {
                value: item.ne.id,
                label: item.ne.userlabel,
                info: item,
                wans: node.data.info.wans,
                leaf: level >= 3
              };
            });
            resolve(nes);
          }
        }
        // 四级
        if (level === 3) {
          let wans = node.data.wans;
          let info = node.data.info;
          let wan = [];
          wans.map(it => {
            if (it.standByRelation === info.standByRelation) {
              wan.push({
                value: it.name,
                label: it.alias,
                wan: it,
                leaf: level >= 3
              });
            }
          });
          resolve(wan);
        }
      }
    };
  },
  // 过滤
  filters: {},
  data () {
    return {
      site: {},
      startOptions: {},
      endOptions: {},
      // VPN列表
      vpnls: [],
      form: {
        userlabel: null,
        tunnelType: null,
        priority: null,
        start: [],
        ipVersion: null,
        enableVpn: false,
        vpnId: null,
        end: [],
        enableSqa: false,
        speed: false,
        rateLimit: 0,
        startNeIpsecIp: null,
        startMask: 30,
        endNeIpsecIp: null,
        endMask: 30
      },
      rules: {
        userlabel: [{
          required: true,
          message: '请填写名称',
          trigger: 'blur'
        }],
        tunnelType: [{
          required: true,
          message: '请选择类型',
          trigger: 'change'
        }],
        ipVersion: [{
          required: true,
          message: '请选择IP类型',
          trigger: 'change'
        }],
        priority: [{
          required: true,
          message: '请选择优先级',
          trigger: 'change'
        }],
        start: [{
          required: true,
          message: '请选择源端',
          trigger: 'change'
        }],
        end: [{
          required: true,
          message: '请选择目的端',
          trigger: 'change'
        }]
      }
    };
  },
  methods: {
    // 数组去重
    uniqueArr (arr, id) {
      if (arr.length === 0) {
        return;
      }
      for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length; j++) {
          if (arr[i][id] === arr[j][id]) {
            arr.splice(j, 1);
            j--;
          }
        }
      }
      return arr;
    },
    handleChange (val) {
      let _this = this;
      if (val.length === 0) {
        _this.form.vpnId = null;
        _this.form.end = [];
      } else {
        _this.form.vpnId = null;
        _this.form.end = [];
      }
    },
    // 返回
    cancel () {
      let _this = this;
      _this.$emit('handleChange', 0);
    },
    submitForm (formName) {
      let _this = this;
      _this.$refs[formName].validate(async (valid) => {
        if (valid) {
          let tenants = _this.tenants;
          let tenant = tenants.find(it => {
            return _this.form.start[0] === it.value;
          });
          // 隧道参数
          let params = {
            sdwanLink: {
              // 租户ID - 源端
              dgId: tenant.value,
              // 租户名称 - 源端
              orgName: tenant.label,
              // 源站点
              startSite: _this.form.start[1],
              // 源设备
              startNe: _this.form.start[2],
              // 源端口
              startWan: _this.form.start[3],
              // 隧道名称
              userlabel: _this.form.userlabel,
              // 隧道类型
              tunnelType: _this.form.tunnelType,
              // 优先级
              extAttrs: {
                priority: _this.form.priority,
                startNeIpsecIp: _this.form.startNeIpsecIp ? _this.form.startNeIpsecIp + '/' + _this.form.startMask : null,
                endNeIpsecIp: _this.form.endNeIpsecIp ? _this.form.endNeIpsecIp + '/' + _this.form.endMask : null,
              },
              // 开启VPN
              enableVpn: _this.form.enableVpn,
              // VPN
              vpnId: _this.form.enableVpn ? _this.form.vpnId : null,
              // 目的站点
              endSite: _this.form.end[1],
              // 目的设备
              endNe: _this.form.end[2],
              // 目的端口
              endWan: _this.form.end[3],
              // 开启监控
              enableSqa: _this.form.enableSqa,
              // 开启限速
              rateLimit: _this.form.speed ? _this.form.rateLimit : 0
            },
            // 源端站点类型
            accessDeviceType: _this.site.siteType
          };
          _this.portStatus(_this.form.startNeIpsecIp, _this.form.endNeIpsecIp, params);
        } else {
          this.$message.error('请检查必填项！');
          return false;
        }
      });
    },
    resetForm (formName) {
      this.$refs[formName].resetFields();
      this.form = {
        userlabel: null,
        tunnelType: null,
        ipVersion: null,
        priority: null,
        start: [],
        enableVpn: false,
        vpnId: null,
        end: [],
        enableSqa: false,
        speed: false,
        rateLimit: 0,
        startNeIpsecIp: null,
        startMask: 30,
        endNeIpsecIp: null,
        endMask: 30
      };
    },
    // 过滤端口状态
    // eslint-disable-next-line complexity
    portStatus (start, end, data) {
      let _this = this;
      let params = {
        commandCode: 'statics.ports',
        paras: {
          isWAN: true,
          status: 1
        }
      };
      let errs = [];
      let ipv4 = /^(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$/;
      let ipv6 = /^([\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^::([\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:):([\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){2}:([\da-fA-F]{1,4}:){0,2}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){3}:([\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}$|^:((:[\da-fA-F]{1,4}){1,6}|:)$|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)$|^([\da-fA-F]{1,4}:){2}((:[\da-fA-F]{1,4}){1,4}|:)$|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,4}){1,3}|:)$|^([\da-fA-F]{1,4}:){4}((:[\da-fA-F]{1,4}){1,2}|:)$|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?$|^([\da-fA-F]{1,4}:){6}:$/;
      if (start === '' || start === null || end === '' || end === null || _this.form.startMask === '' || _this.form.startMask === null || _this.form.endMask === '' || _this.form.endMask === null) {
        errs.push('接口地址/掩码不能为空！');
      }
      if (_this.form.ipVersion === 'V4') {
        if (start && end) {
          if (start === end) {
            errs.push('接口地址不能相同！');
          }
          if (start.replace(ipv4) !== 'undefined' || end.replace(ipv4) !== 'undefined') {
            errs.push('接口IP格式不正确！');
          }
          if (_this.form.startMask < 0 || _this.form.startMask > 30) {
            errs.push('掩码范围：0-30');
          }
          if (_this.form.endMask < 0 || _this.form.endMask > 30) {
            errs.push('掩码范围：0-30');
          }
        }
      } else {
        if (start === end) {
          errs.push('接口地址不能相同！');
        }
        if (start.replace(ipv6) !== 'undefined' || end.replace(ipv6) !== 'undefined') {
          errs.push('接口IP格式不正确！');
        }
        if (_this.form.startMask < 0 || _this.form.startMask > 128) {
          errs.push('掩码范围：0-128');
        }
        if (_this.form.endMask < 0 || _this.form.endMask > 128) {
          errs.push('掩码范围：0-128');
        }
      }
      Promise.all([
        _this.$http.post({
          url: '/api/resource/nemng/command/' + data.sdwanLink.startNe,
          data: params
        }),
        _this.$http.post({
          url: '/api/resource/nemng/command/' + data.sdwanLink.endNe,
          data: params
        })
      ]).then(res => {
        for (let i = 0; i < res[0].length; i++) {
          if (res[0][i].name === data.sdwanLink.startWan) {
            if (res[0][i].status) {
              errs.push('源端端口状态异常');
            }
          }
        }
        for (let j = 0; j < res[1].length; j++) {
          if (res[1][j].name === data.sdwanLink.endWan) {
            if (res[1][j].status) {
              errs.push('目的端端口状态异常');
            }
          }
        }
      });
      if (errs.length === 0) {
        // 创建隧道请求
        _this.$http.post({
          url: '/api/sdwan/businesslayout/create',
          data: data,
          loading: true
        }).then(res => {
          let { status } = res;
          if (status === '0') {
            _this.$message.success('创建成功！');
            _this.resetForm('tunnelForm');
            _this.cancel();
            _this.$parent.refresh();
          }
        });
      } else {
        if (errs[0] === '源端端口状态异常' || errs[0] === '目的端端口状态异常') {
          this.$confirm(errs[0] + ', 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            // 创建隧道请求
            _this.$http.post({
              url: '/api/sdwan/businesslayout/create',
              data: data,
              loading: true
            }).then(res => {
              let { status } = res;
              if (status === '0') {
                _this.$message.success('创建成功！');
                _this.resetForm('tunnelForm');
                _this.cancel();
                _this.$parent.refresh();
              }
            });
          }).catch(() => {
            _this.$message({
              type: 'info',
              message: '已取消创建'
            });
          });
        } else {
          _this.$message.error(errs[0]);
        }
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.tunnel-content {
  .header {
    background: #fff;
    padding: 30px 40px;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;

    .left-wrap {
      .avatar {
        width: 110px;
        height: 110px;
        object-fit: cover;
        border-radius: 50%;
      }

      h2 {
        font-size: 30px;
        margin-top: 20px;
        font-weight: 500;
      }

      p {
        color: #9ca3ae;
        font-size: 14px;
        margin-top: 20px;
        display: none;
      }

      .task {
        margin-top: 30px;
        display: flex;
        align-items: center;

        span {
          color: #9ca3ae;
          font-size: 14px;
          margin-right: 30px;
          margin-left: 8px;
        }
      }
    }

    .right-wrap {
      display: flex;
      align-items: center;

      img {
        width: 230px;
      }
    }
  }

  .info {
    background: #fff;

    .title {
      font-size: 22px;
      font-weight: 500;
      padding: 15px 40px;
      border-bottom: 1px solid #eee;
    }

    .form {
      padding: 30px 40px;
      box-sizing: border-box;

      .ip-mask {
        width: 100%;
        ::v-deep .el-input {
          float: left;
        }
        ::v-deep .el-input:first-child {
          width: 75%;
        }
        label {
          display: block;
          width: 3%;
          float: left;
          text-align: center;
        }
        ::v-deep .el-input:last-child {
          width: 22%;
          &::after {
            content: "";
            overflow: hidden;
            clear: both;
          }
        }
      }
    }
  }
}

@media only screen and (max-width: $device-ipad) {
  .tunnel-content {
    .header {
      padding: 20px 20px;

      .left-wrap {
        .avatar {
          width: 90px;
          height: 90px;
        }

        h2 {
          font-size: 20px;
          margin-top: 20px;
        }

        .task {
          margin-top: 15px;

          .icon {
            width: 2.8em;
            height: 2.8em;
            vertical-align: -0.15em;
          }

          span {
            font-size: 15px;
          }
        }
      }

      .right-wrap {
        display: flex;
        align-items: center;

        img {
          display: none;
        }
      }
    }

    .info {
      .title {
        font-size: 18px;
        padding: 15px 20px;
      }

      .form {
        padding: 30px 20px;
      }
    }
  }
}
</style>